/**
 * @file bsp_rtc.c
 * @author liufeng (liufeng@injoinic.com)
 * @brief rtc bsp function.
 * @version 0.1
 * @date 2024-11-04
 *
 * @copyright Copyright (c) 2024  injoinic
 *
 */

#include "bsp_rtc.h"
#include "main.h"
#include "stdio.h"

/**
 * @brief get RTC time(Beijing), and convert it to unix timestamp.
 * @return uint32_t: unix timestamp.
 */
uint32_t rtc_to_timestamp()
{
    LL_RTC_TimeTypeDef gTime;
    LL_RTC_DateTypeDef gDate;
    rtc_get(&gTime, &gDate);

    struct tm time = {0};
    time.tm_hour = gTime.Hours - 8;
    time.tm_min = gTime.Minutes;
    time.tm_sec = gTime.Seconds;
    time.tm_year = gDate.Year + 100;
    time.tm_mon = gDate.Month - 1;
    time.tm_mday = gDate.Day;
    time.tm_wday = gDate.WeekDay;

    uint32_t timestamp = mktime(&time);
    return timestamp;
}

/**
 * @brief convert unix timestamp to RTC time(Beijing) and date struct.
 * @param[in] timestamp unix_timestamp:https://www.json.cn/unixtime/
 * @param[in] gTime RTC time @struct LL_RTC_TimeTypeDef.
 * @param[in] gDate RTC date @struct LL_RTC_DateTypeDef.
 */
void timestamp_to_rtc(uint32_t timestamp, LL_RTC_TimeTypeDef* gTime, LL_RTC_DateTypeDef* gDate)
{
    struct tm* time = localtime(&timestamp);

    gTime->Hours = time->tm_hour + 8;
    gTime->Minutes = time->tm_min;
    gTime->Seconds = time->tm_sec;

    gDate->Year = time->tm_year - 100;
    gDate->Month = time->tm_mon + 1;
    gDate->Day = time->tm_mday;
    gDate->WeekDay = time->tm_wday;
}

/**
 * @brief set RTC time(Beijing) and date, bin format.
 * @param[in] gTime RTC time @struct LL_RTC_TimeTypeDef.
 * @param[in] gDate RTC date @struct LL_RTC_DateTypeDef.
 */
void rtc_set(LL_RTC_TimeTypeDef* sTime, LL_RTC_DateTypeDef* sDate)
{
    LL_RTC_TIME_Init(RTC, LL_RTC_FORMAT_BIN, sTime);
    LL_RTC_DATE_Init(RTC, LL_RTC_FORMAT_BIN, sDate);
}

/**
 * @brief get RTC time(Beijing) and date, bin format.
 * @param[in] gTime RTC time @struct LL_RTC_TimeTypeDef.
 * @param[in] gDate RTC date @struct LL_RTC_DateTypeDef.
 */
void rtc_get(LL_RTC_TimeTypeDef* gTime, LL_RTC_DateTypeDef* gDate)
{
    gTime->Hours = __LL_RTC_CONVERT_BCD2BIN(LL_RTC_TIME_GetHour(RTC));
    gTime->Minutes = __LL_RTC_CONVERT_BCD2BIN(LL_RTC_TIME_GetMinute(RTC));
    gTime->Seconds = __LL_RTC_CONVERT_BCD2BIN(LL_RTC_TIME_GetSecond(RTC));

    gDate->Year = __LL_RTC_CONVERT_BCD2BIN(LL_RTC_DATE_GetYear(RTC));
    gDate->Month = __LL_RTC_CONVERT_BCD2BIN(LL_RTC_DATE_GetMonth(RTC));
    gDate->Day = __LL_RTC_CONVERT_BCD2BIN(LL_RTC_DATE_GetDay(RTC));
    gDate->WeekDay = __LL_RTC_CONVERT_BCD2BIN(LL_RTC_DATE_GetWeekDay(RTC));
}
